package org.luxor.cloud.authentication.component.captcha;

import com.octo.captcha.Captcha;
import com.octo.captcha.service.CaptchaServiceException;
import com.octo.captcha.service.captchastore.CaptchaAndLocale;
import com.octo.captcha.service.captchastore.CaptchaStore;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.Collection;
import java.util.Locale;

/**
 * Redis验证码存储器
 *
 * @author Mr.Yan  @date: 2021/1/8
 */
public class RedisCaptchaStore implements CaptchaStore {

    private static final String CAPTCHA_KEY_PREFIX = "captcha";

    private RedisTemplate<Object, Object> redisTemplate;

    public RedisCaptchaStore(RedisTemplate<Object, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Override
    public boolean hasCaptcha(String id) {
        return redisTemplate.opsForHash().hasKey(CAPTCHA_KEY_PREFIX, id);
    }

    @Override
    public void storeCaptcha(String id, Captcha captcha) throws CaptchaServiceException {
        redisTemplate.opsForHash().put(CAPTCHA_KEY_PREFIX, id, new CaptchaAndLocale(captcha));
    }

    @Override
    public void storeCaptcha(String id, Captcha captcha, Locale locale) throws CaptchaServiceException {
        redisTemplate.opsForHash().put(CAPTCHA_KEY_PREFIX, id, new CaptchaAndLocale(captcha, locale));
    }

    @Override
    public Captcha getCaptcha(String id) throws CaptchaServiceException {
        Object result = redisTemplate.opsForHash().get(CAPTCHA_KEY_PREFIX, id);
        if (result == null) {
            return null;
        }
        CaptchaAndLocale captchaAndLocale = (CaptchaAndLocale) result;
        return captchaAndLocale.getCaptcha();
    }

    @Override
    public Locale getLocale(String id) throws CaptchaServiceException {
        Object result = redisTemplate.opsForHash().get(CAPTCHA_KEY_PREFIX, id);
        if (result == null) {
            return null;
        }
        CaptchaAndLocale captchaAndLocale = (CaptchaAndLocale) result;
        return captchaAndLocale.getLocale();
    }

    @Override
    public boolean removeCaptcha(String id) {
        return redisTemplate.opsForHash().delete(CAPTCHA_KEY_PREFIX, id) != 0;
    }

    @Override
    public int getSize() {
        return Math.toIntExact(redisTemplate.opsForHash().size(CAPTCHA_KEY_PREFIX));
    }

    @Override
    public Collection getKeys() {
        return redisTemplate.opsForHash().keys(CAPTCHA_KEY_PREFIX);
    }

    @Override
    public void empty() {
        redisTemplate.delete(CAPTCHA_KEY_PREFIX);
    }
}
